package com.talentgame.tankspk.GameCore;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.g3d.Model;
import com.badlogic.gdx.graphics.g3d.ModelInstance;
import com.badlogic.gdx.graphics.g3d.model.Node;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Quaternion;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.BoundingBox;
import com.badlogic.gdx.physics.bullet.collision.Collision;
import com.badlogic.gdx.physics.bullet.collision.btBoxShape;
import com.badlogic.gdx.physics.bullet.collision.btCollisionObject;
import com.badlogic.gdx.physics.bullet.collision.btCollisionShape;
import com.badlogic.gdx.physics.bullet.dynamics.btContactConstraint;
import com.badlogic.gdx.physics.bullet.dynamics.btFixedConstraint;
import com.badlogic.gdx.physics.bullet.dynamics.btGeneric6DofSpringConstraint;
import com.badlogic.gdx.physics.bullet.dynamics.btRigidBody;
import com.badlogic.gdx.physics.bullet.dynamics.btTypedConstraint;
import com.badlogic.gdx.physics.bullet.linearmath.btTransform;
import com.badlogic.gdx.scenes.scene2d.ui.Touchpad;
import com.badlogic.gdx.utils.Disposable;
import com.talentgame.tankspk.GameNet.DTO.PlayerModel;

/**
 * Created by 54560 on 2016/12/18.
 *
 * 记住！旋转是需要在原点旋转的，所以这里一般是 先translate 再rotate ,得到的矩阵就是 先旋转 后平移的，因为矩阵相乘后，最后右乘向量
 * 而trn 的方法则只修改 矩阵的第4列，可以跳过以上问题,书 101页有说
 */
public class Tank extends GameObject implements Disposable{
    public float speed = 5;
    Node turret;//炮台
    String bulletId;
    public int playerid;
    private Vector3 shotPos =new Vector3();

    private Vector3 lookDirection = new Vector3();
    private Vector3 tankDirection = new Vector3();

    private PlayerModel playerModel = new PlayerModel();

    //public Vector3 lastModelPos =new Vector3();
    public Vector3 destPos = new Vector3();
    public PlayerModel GetPlayerModel()
    {
        Vector3 pos = getPosition();
        playerModel.Set(pos.x,pos.y,pos.z,tankDirection.x,tankDirection.y,tankDirection.z,lookDirection.x,lookDirection.y,lookDirection.z);
        return this.playerModel;
    }
    public Tank(Model model, String nodeId, String bulletId,int playerid) {
        super(model,nodeId);
        this.playerid = playerid;
        this.bulletId = bulletId;
        //获取炮台
        turret = this.nodes.get(0).getChild(0).getChild(0);
        //让坦克网上升1点
        transform.trn(0,3,0);
        body.proceedToTransform(this.transform);
        //body.setDamping(1,1);
        //body.setFriction(100);

        body.setCollisionFlags(body.getCollisionFlags() | btCollisionObject.CollisionFlags.CF_CUSTOM_MATERIAL_CALLBACK);
        body.setContactCallbackFlag(TanksGame.PLAYER_FLAG);
        body.setContactCallbackFilter(TanksGame.OBJECT_FLAG);

    }

    @Override
    public GameObject copy() {
        return new GameObject(this);
    }

    @Override
    protected btRigidBody.btRigidBodyConstructionInfo getConstructionInfo() {
        SetMass(10);
        return super.getConstructionInfo();
    }
    public void Move(Vector3 direction,float detaltime,boolean isLerp)
    {
        direction = direction.nor();
        this.tankDirection = direction;
        Matrix4 tempTran = transform.cpy();
        //获取坦克正前方
        Vector3 forward = getForward(transform);
        forward = new Vector3(forward.x,0,forward.z);
        if(isLerp)
            direction = forward.lerp(new Vector3(direction.x,direction.y,direction.z),detaltime*12);
        tempTran.setToLookAt(new Vector3(direction.x,direction.y,-direction.z),Vector3.Y) ;
        tempTran.trn((transform.getTranslation(new Vector3()))).trn(direction.scl(detaltime * speed));

        transform.set(tempTran);
//        this.tankDirection = direction;
        body.proceedToTransform(transform);
    }

    public void SetSync(PlayerModel model)
    {
        this.playerModel = model;
        Vector3 position = new Vector3(model.x,model.y,model.z);
        Vector3 tankDirection = new Vector3(model.tdx,model.tdy,model.tdz);
        Vector3 lookDirection = new Vector3(model.ldx,model.ldy,model.ldz);

        this.tankDirection = tankDirection;
        this.lookDirection = lookDirection;

        if (tankDirection.x != 0&& tankDirection.z != 0)
        {
            transform.setToLookAt(new Vector3(tankDirection.x,tankDirection.y,-tankDirection.z),Vector3.Y);
            transform.trn(position);
        }else
        {
               transform.idt();
               transform.trn(position);
        }
        if(playerModel.isLook)
            setTurretLookAt(lookDirection);
        if(playerModel.isShot)
            shotBullet();
        body.proceedToTransform(transform);
    }
    //从网络端同步的数据
    public void Sync(PlayerModel model)
    {
        this.playerModel = model;
        if(playerModel.isShot)
            shotBullet();
    }
    public void setTurretLookAt(Vector3 direction)
    {
        try{
            this.lookDirection = direction;
            Matrix4 tempTran = transform.cpy();
            tempTran.setToLookAt(new Vector3(direction.x,direction.y,direction.z),Vector3.Y);
            turret.rotation.setFromMatrix(tempTran.mul(transform.cpy().inv())); //用inv 去掉原本坦克的旋转
            calculateTransforms();
        }catch (Exception e){

        }

    }

    @Override
    public void update(float detalTime) {
        super.update(detalTime);
        if(playerid != TanksGame.instance.playerid) //如果是别的玩家
        {
            if(playerModel == null)return;
            PlayerModel model = this.playerModel;
            Vector3 position = new Vector3(model.x,model.y,model.z);
            Vector3 tankDirection = new Vector3(model.tdx,model.tdy,model.tdz);
            Vector3 lookDirection = new Vector3(model.ldx,model.ldy,model.ldz);

            Vector3 currentPos = getPosition().cpy();
            float dis = new Vector3(currentPos.x,0,currentPos.z).dst(new Vector3(position.x,0,position.z));
            float detalSpeed = speed * detalTime;
            float step = 0.008f;

            //Vector3 direction = getForward(this.transform).cpy();
            //Gdx.app.log("testForward",direction.nor() +"    " +tankDirection.nor() );
//            float directionDis = new Vector3(tankDirection.x,tankDirection.y,tankDirection.z).nor().dst(new Vector3(direction.x,direction.y,direction.z).nor());
//            if(directionDis > 0.01f)
//            {
//                SetSync(model);
//                Vector3 pos = transform.getTranslation(new Vector3());
//                if (tankDirection.x != 0  && tankDirection.z != 0)
//                {
//                    transform.setToLookAt(new Vector3(tankDirection.x,tankDirection.y,-tankDirection.z),Vector3.Y);
//                    transform.trn(pos);
//                    Gdx.app.log("旋转","直接同步旋转 ： pos " + pos + "  direction " + tankDirection);
//                }
//
//            }
            if(dis > step)
            {
                if(dis > detalSpeed)
                {
                    Gdx.app.log("同步前","dis :" + dis  +" detalspped : " + detalSpeed +  "  当前位置 " + currentPos.toString() + "    目标位置 :"  + position) ;
                    Vector3 newDiretion = new Vector3(position.x,0,position.z).sub(new Vector3(currentPos.x,0,currentPos.z)).nor();
                    Move(newDiretion,detalTime,false);
                    currentPos = getPosition().cpy();
                    dis = new Vector3(currentPos.x,0,currentPos.z).dst(new Vector3(position.x,0,position.z));
                    Gdx.app.log("同步后","dis :" + dis  +" detalspped : " + detalSpeed +  "  当前位置 " + currentPos + "     目标位置 :"  + position);
                }
                else
                {
                    SetSync(model);
                    //Gdx.app.log("同步","直接同步");
                }
            }
            if(playerModel.isLook)
            setTurretLookAt(lookDirection);
        }
    }

    /*
    * 发射子弹
    * */
    public void shotBullet()
    {
        TanksGame.instance.shotSound.play();

        TankBullet bullet = new TankBullet(this.model,bulletId,this.playerid);
        bullet.transform.getTranslation(shotPos);
        shotPos.z += 0.4f;
        Matrix4 tempTran = new Matrix4();
        tempTran.setToLookAt(new Vector3(lookDirection.x,lookDirection.y,lookDirection.z),Vector3.Y);
        shotPos.mul(this.transform.cpy().rotate(turret.rotation));
        instantiate(bullet,true,shotPos,tempTran.getRotation(new Quaternion()));
    }


    @Override
    public void dispose() {
        super.dispose();
    }
}
